<!DOCTYPE html>



  


<html class="theme-next gemini use-motion" lang="zh-Hans">
<head>
  <meta charset="UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1"/>
<meta name="theme-color" content="#222">









<meta http-equiv="Cache-Control" content="no-transform" />
<meta http-equiv="Cache-Control" content="no-siteapp" />
















  
  
  <link href="/blog/lib/fancybox/source/jquery.fancybox.css?v=2.1.5" rel="stylesheet" type="text/css" />




  
  
  
  

  
    
    
  

  
    
      
    

    
  

  

  
    
      
    

    
  

  
    
      
    

    
  

  
    
    
    <link href="//fonts.googleapis.com/css?family=Monda:300,300italic,400,400italic,700,700italic|Roboto Slab:300,300italic,400,400italic,700,700italic|PT Mono:300,300italic,400,400italic,700,700italic|PT Mono:300,300italic,400,400italic,700,700italic&subset=latin,latin-ext" rel="stylesheet" type="text/css">
  






<link href="/blog/lib/font-awesome/css/font-awesome.min.css?v=4.6.2" rel="stylesheet" type="text/css" />

<link href="/blog/css/main.css?v=5.1.4" rel="stylesheet" type="text/css" />


  <link rel="apple-touch-icon" sizes="180x180" href="/blog/images/apple-touch-icon-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="32x32" href="/blog/images/favicon-32x32-next.png?v=5.1.4">


  <link rel="icon" type="image/png" sizes="16x16" href="/blog/images/favicon-16x16-next.png?v=5.1.4">


  <link rel="mask-icon" href="/blog/images/logo.svg?v=5.1.4" color="#222">





  <meta name="keywords" content="HTTP,计算机网络," />










<meta name="description" content="1.HTTP简述（出自MDN）超文本传输协议（HTTP）是用于传输诸如HTML的超媒体文档的应用层协议。它被设计用于Web浏览器和Web服务器之间的通信，但它也可以用于其他目的。 HTTP遵循经典的客户端-服务端模型，客户端打开一个连接以发出请求，然后等待它收到服务器端响应。 HTTP是无状态协议，意味着服务器不会在两个请求之间保留任何数据（状态）。虽然通常基于TCP / IP层，但可以在任何可靠">
<meta name="keywords" content="HTTP,计算机网络">
<meta property="og:type" content="article">
<meta property="og:title" content="那些前端应该知道的HTTP知识">
<meta property="og:url" content="http://srtian96.gitee.io/blog/2018/05/15/那些前端应该知道的HTTP知识/index.html">
<meta property="og:site_name" content="Srtian&#39;Blog">
<meta property="og:description" content="1.HTTP简述（出自MDN）超文本传输协议（HTTP）是用于传输诸如HTML的超媒体文档的应用层协议。它被设计用于Web浏览器和Web服务器之间的通信，但它也可以用于其他目的。 HTTP遵循经典的客户端-服务端模型，客户端打开一个连接以发出请求，然后等待它收到服务器端响应。 HTTP是无状态协议，意味着服务器不会在两个请求之间保留任何数据（状态）。虽然通常基于TCP / IP层，但可以在任何可靠">
<meta property="og:locale" content="zh-Hans">
<meta property="og:image" content="https://user-gold-cdn.xitu.io/2018/5/15/16363db6cb586fb4?w=250&h=386&f=png&s=6320">
<meta property="og:image" content="https://user-gold-cdn.xitu.io/2018/5/15/16363db6303ec20c?w=477&h=209&f=png&s=8484">
<meta property="og:image" content="https://user-gold-cdn.xitu.io/2018/5/15/16363db63206ea64?w=477&h=207&f=png&s=9127">
<meta property="og:image" content="https://user-gold-cdn.xitu.io/2018/5/15/16363db635d64a71?w=1194&h=589&f=png&s=135258">
<meta property="og:image" content="https://user-gold-cdn.xitu.io/2018/5/15/16363db645ff9125?w=579&h=216&f=png&s=67613">
<meta property="og:image" content="https://user-gold-cdn.xitu.io/2018/5/15/16363db62f311590?w=576&h=105&f=png&s=30845">
<meta property="og:image" content="https://user-gold-cdn.xitu.io/2018/5/15/16363db63377aff6?w=599&h=259&f=png&s=24567">
<meta property="og:image" content="https://user-gold-cdn.xitu.io/2018/5/15/16363db6cfd402bf?w=578&h=243&f=png&s=28374">
<meta property="og:image" content="https://user-gold-cdn.xitu.io/2018/5/15/16363db6d2077346?w=637&h=270&f=png&s=59536">
<meta property="og:image" content="https://user-gold-cdn.xitu.io/2018/5/15/16363db6e9f972fc?w=601&h=243&f=png&s=51496">
<meta property="og:image" content="https://user-gold-cdn.xitu.io/2018/5/15/16363db6e0576c28?w=705&h=1344&f=jpeg&s=151236">
<meta property="og:image" content="https://user-gold-cdn.xitu.io/2018/5/15/16363db6f24e7667?w=588&h=91&f=png&s=24582">
<meta property="og:image" content="https://user-gold-cdn.xitu.io/2018/5/15/16363db6fdc9f9e2?w=640&h=485&f=jpeg&s=37246">
<meta property="og:image" content="https://user-gold-cdn.xitu.io/2018/5/15/16363db708db432c?w=395&h=228&f=jpeg&s=13767">
<meta property="og:image" content="https://user-gold-cdn.xitu.io/2018/5/15/16363db70a13a202?w=690&h=496&f=jpeg&s=75157">
<meta property="og:updated_time" content="2018-07-19T14:14:40.731Z">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="那些前端应该知道的HTTP知识">
<meta name="twitter:description" content="1.HTTP简述（出自MDN）超文本传输协议（HTTP）是用于传输诸如HTML的超媒体文档的应用层协议。它被设计用于Web浏览器和Web服务器之间的通信，但它也可以用于其他目的。 HTTP遵循经典的客户端-服务端模型，客户端打开一个连接以发出请求，然后等待它收到服务器端响应。 HTTP是无状态协议，意味着服务器不会在两个请求之间保留任何数据（状态）。虽然通常基于TCP / IP层，但可以在任何可靠">
<meta name="twitter:image" content="https://user-gold-cdn.xitu.io/2018/5/15/16363db6cb586fb4?w=250&h=386&f=png&s=6320">



<script type="text/javascript" id="hexo.configurations">
  var NexT = window.NexT || {};
  var CONFIG = {
    root: '/blog/',
    scheme: 'Gemini',
    version: '5.1.4',
    sidebar: {"position":"left","display":"post","offset":12,"b2t":false,"scrollpercent":false,"onmobile":false},
    fancybox: true,
    tabs: true,
    motion: {"enable":true,"async":false,"transition":{"post_block":"fadeIn","post_header":"slideDownIn","post_body":"slideDownIn","coll_header":"slideLeftIn","sidebar":"slideUpIn"}},
    duoshuo: {
      userId: '0',
      author: '博主'
    },
    algolia: {
      applicationID: '',
      apiKey: '',
      indexName: '',
      hits: {"per_page":10},
      labels: {"input_placeholder":"Search for Posts","hits_empty":"We didn't find any results for the search: ${query}","hits_stats":"${hits} results found in ${time} ms"}
    }
  };
</script>



  <link rel="canonical" href="http://srtian96.gitee.io/blog/2018/05/15/那些前端应该知道的HTTP知识/"/>





  <title>那些前端应该知道的HTTP知识 | Srtian'Blog</title>
  








</head>

<body itemscope itemtype="http://schema.org/WebPage" lang="zh-Hans">

  
  
    
  

  <div class="container sidebar-position-left page-post-detail">
    <div class="headband"></div>

    <header id="header" class="header" itemscope itemtype="http://schema.org/WPHeader">
      <div class="header-inner"><div class="site-brand-wrapper">
  <div class="site-meta ">
    

    <div class="custom-logo-site-title">
      <a href="/blog/"  class="brand" rel="start">
        <span class="logo-line-before"><i></i></span>
        <span class="site-title">Srtian'Blog</span>
        <span class="logo-line-after"><i></i></span>
      </a>
    </div>
      
        <p class="site-subtitle">It's better to burn out than to fade away</p>
      
  </div>

  <div class="site-nav-toggle">
    <button>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
      <span class="btn-bar"></span>
    </button>
  </div>
</div>

<nav class="site-nav">
  

  
    <ul id="menu" class="menu">
      
        
        <li class="menu-item menu-item-home">
          <a href="/blog/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-home"></i> <br />
            
            首页
          </a>
        </li>
      
        
        <li class="menu-item menu-item-about">
          <a href="/blog/about/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-user"></i> <br />
            
            关于
          </a>
        </li>
      
        
        <li class="menu-item menu-item-tags">
          <a href="/blog/tags/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-tags"></i> <br />
            
            标签
          </a>
        </li>
      
        
        <li class="menu-item menu-item-categories">
          <a href="/blog/categories/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-th"></i> <br />
            
            分类
          </a>
        </li>
      
        
        <li class="menu-item menu-item-archives">
          <a href="/blog/archives/" rel="section">
            
              <i class="menu-item-icon fa fa-fw fa-archive"></i> <br />
            
            归档
          </a>
        </li>
      

      
        <li class="menu-item menu-item-search">
          
            <a href="javascript:;" class="popup-trigger">
          
            
              <i class="menu-item-icon fa fa-search fa-fw"></i> <br />
            
            搜索
          </a>
        </li>
      
    </ul>
  

  
    <div class="site-search">
      
  <div class="popup search-popup local-search-popup">
  <div class="local-search-header clearfix">
    <span class="search-icon">
      <i class="fa fa-search"></i>
    </span>
    <span class="popup-btn-close">
      <i class="fa fa-times-circle"></i>
    </span>
    <div class="local-search-input-wrapper">
      <input autocomplete="off"
             placeholder="搜索..." spellcheck="false"
             type="text" id="local-search-input">
    </div>
  </div>
  <div id="local-search-result"></div>
</div>



    </div>
  
</nav>



 </div>
    </header>

    <main id="main" class="main">
      <div class="main-inner">
        <div class="content-wrap">
          <div id="content" class="content">
            

  <div id="posts" class="posts-expand">
    

  

  
  
  

  <article class="post post-type-normal" itemscope itemtype="http://schema.org/Article">
  
  
  
  <div class="post-block">
    <link itemprop="mainEntityOfPage" href="http://srtian96.gitee.io/blog/blog/2018/05/15/那些前端应该知道的HTTP知识/">

    <span hidden itemprop="author" itemscope itemtype="http://schema.org/Person">
      <meta itemprop="name" content="Srtian">
      <meta itemprop="description" content="">
      <meta itemprop="image" content="/blog/images/avatar.jpg">
    </span>

    <span hidden itemprop="publisher" itemscope itemtype="http://schema.org/Organization">
      <meta itemprop="name" content="Srtian'Blog">
    </span>

    
      <header class="post-header">

        
        
          <h1 class="post-title" itemprop="name headline">那些前端应该知道的HTTP知识</h1>
        

        <div class="post-meta">
          <span class="post-time">
            
              <span class="post-meta-item-icon">
                <i class="fa fa-calendar-o"></i>
              </span>
              
                <span class="post-meta-item-text">发表于</span>
              
              <time title="创建于" itemprop="dateCreated datePublished" datetime="2018-05-15T23:47:07+08:00">
                2018-05-15
              </time>
            

            

            
          </span>

          
            <span class="post-category" >
            
              <span class="post-meta-divider">|</span>
            
              <span class="post-meta-item-icon">
                <i class="fa fa-folder-o"></i>
              </span>
              
                <span class="post-meta-item-text">分类于</span>
              
              
                <span itemprop="about" itemscope itemtype="http://schema.org/Thing">
                  <a href="/blog/categories/计算机网络/" itemprop="url" rel="index">
                    <span itemprop="name">计算机网络</span>
                  </a>
                </span>

                
                
              
            </span>
          

          
            
          

          
          

          
            <span class="post-meta-divider">|</span>
            <span class="page-pv">本文总阅读量
            <span class="busuanzi-value" id="busuanzi_value_page_pv" ></span>次
            </span>
          

          
            <div class="post-wordcount">
              
                
                <span class="post-meta-item-icon">
                  <i class="fa fa-file-word-o"></i>
                </span>
                
                  <span class="post-meta-item-text">字数统计&#58;</span>
                
                <span title="字数统计">
                  4,301
                </span>
              

              
                <span class="post-meta-divider">|</span>
              

              
                <span class="post-meta-item-icon">
                  <i class="fa fa-clock-o"></i>
                </span>
                
                  <span class="post-meta-item-text">阅读时长 &asymp;</span>
                
                <span title="阅读时长">
                  16
                </span>
              
            </div>
          

          

        </div>
      </header>
    

    
    
    
    <div class="post-body" itemprop="articleBody">

      
      

      
        <h3 id="1-HTTP简述（出自MDN）"><a href="#1-HTTP简述（出自MDN）" class="headerlink" title="1.HTTP简述（出自MDN）"></a>1.HTTP简述（出自MDN）</h3><p>超文本传输协议（HTTP）是用于传输诸如HTML的超媒体文档的应用层协议。它被设计用于Web浏览器和Web服务器之间的通信，但它也可以用于其他目的。 HTTP遵循经典的客户端-服务端模型，客户端打开一个连接以发出请求，然后等待它收到服务器端响应。 HTTP是无状态协议，意味着服务器不会在两个请求之间保留任何数据（状态）。虽然通常基于TCP / IP层，但可以在任何可靠的传输层上使用.</p>
<h3 id="2-URL和URI"><a href="#2-URL和URI" class="headerlink" title="2.URL和URI"></a>2.URL和URI</h3><p>我们经常会接触到URL（统一资源定位符），它就是我们用于访问web的一个字符串地址.而URI对我们来讲就相对比较陌生了，它的名字叫做统一资源标识符（URI）。我们来看看它们具体的区别吧：</p>
<ul>
<li>URI：uniform resource identifier 统一资源标识符，一种资源的标识，它是一种抽象的资源标识，即可以是相对的，也可以是绝对的。</li>
<li>URL：uniform resource location 统一资源定位符，同时一种资源的标识，但指明了如何定位Locate这个资源。因为它指明了定位的信息，所以必须是绝对的。</li>
</ul>
<p>（我们平时所说的相对地址，其实只是相对于另一个绝对地址而言的）</p>
<h4 id="2-1-URL"><a href="#2-1-URL" class="headerlink" title="2.1 URL"></a>2.1 URL</h4><p>URL的基本格式如下：<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">schema://host[:port#]/path/.../[?query-string][#anchor]</span><br></pre></td></tr></table></figure></p>
<table>
<thead>
<tr>
<th>格式</th>
<th>意义 </th>
</tr>
</thead>
<tbody>
<tr>
<td>scheme</td>
<td>指定低层使用的协议(例如：http, https, ftp)。</td>
</tr>
<tr>
<td>host</td>
<td>HTTP服务器的IP地址或者域名。</td>
</tr>
<tr>
<td>port#</td>
<td>HTTP服务器的默认端口是80，这种情况下端口号可以省略。如果使用了别的端口，必须指明。</td>
</tr>
<tr>
<td>path</td>
<td>访问资源的路径。</td>
</tr>
<tr>
<td>query-string</td>
<td>发送给http服务器的数据。</td>
</tr>
<tr>
<td>anchor-</td>
<td>锚</td>
</tr>
</tbody>
</table>
<h3 id="3-HTTP报文"><a href="#3-HTTP报文" class="headerlink" title="3.HTTP报文"></a>3.HTTP报文</h3><h4 id="3-1-HTTP报文格式"><a href="#3-1-HTTP报文格式" class="headerlink" title="3.1 HTTP报文格式"></a>3.1 HTTP报文格式</h4><p>HTTP的报文格式主要分为报文首部和报文主体：</p>
<p><img src="https://user-gold-cdn.xitu.io/2018/5/15/16363db6cb586fb4?w=250&amp;h=386&amp;f=png&amp;s=6320" alt="image"></p>
<p>其中的空行用于区分报文首部和报文主体内容，是由一个回车符和一个换行符组成的。</p>
<p>无论是请求报文还是响应报文都需要有报文首部，而报文主体有些请求报文是没有的。请求报文的一般格式如下：</p>
<p><img src="https://user-gold-cdn.xitu.io/2018/5/15/16363db6303ec20c?w=477&amp;h=209&amp;f=png&amp;s=8484" alt="image"></p>
<p>而响应报文的格式是这样的：</p>
<p><img src="https://user-gold-cdn.xitu.io/2018/5/15/16363db63206ea64?w=477&amp;h=207&amp;f=png&amp;s=9127" alt="image"></p>
<p>下面是谷歌浏览器的HTTP报文内容，其中request headers描述了请求报文头部的内容，response headers描述了响应报文头部的内容：</p>
<p><img src="https://user-gold-cdn.xitu.io/2018/5/15/16363db635d64a71?w=1194&amp;h=589&amp;f=png&amp;s=135258" alt="image"></p>
<p>其中最常见的属性如下：</p>
<ol>
<li>URL, 即http访问的地址</li>
<li>request method, 报文的请求方式</li>
<li>status code, 状态码以及状态短语</li>
<li>Accept Encoding, 内容编码</li>
<li>Connection, 连接方式</li>
<li>Cookie, 添加的cookie内容</li>
<li>Host, 目标主机</li>
<li>User-Agent, 客户端浏览器的相关信息</li>
<li>Set-Cookie, 指定想要在Cookie中保存的内容</li>
</ol>
<p>接下来就聊一聊这些属性的作用</p>
<h4 id="3-2-HTTP请求方式（request-method）——GET-and-POST"><a href="#3-2-HTTP请求方式（request-method）——GET-and-POST" class="headerlink" title="3.2 HTTP请求方式（request method）——GET and POST"></a>3.2 HTTP请求方式（request method）——GET and POST</h4><p>发送HTTP的方式有很多，但最常用的还是POST和GET。</p>
<ul>
<li><p>GET:GET方法可以用来请求访问已经被URL识别的资源。指定的资源经过服务端解析后返回响应的内容。简单来说，就是请求的资源是文本的话，那么就保持原样返回.<br><img src="https://user-gold-cdn.xitu.io/2018/5/15/16363db645ff9125?w=579&amp;h=216&amp;f=png&amp;s=67613" alt="image"></p>
</li>
<li><p>POST:POST方法可以用来传输实体的主体。</p>
</li>
</ul>
<p><img src="https://user-gold-cdn.xitu.io/2018/5/15/16363db62f311590?w=576&amp;h=105&amp;f=png&amp;s=30845" alt="image"></p>
<p>这两者的区别主要如下：</p>
<ol>
<li>使用目标不同<blockquote>
<p>POST与GET都用于获取信息，但是GET方式仅仅是查询，并不对服务器上的内容产生任何作用结果；每次GET的内容都是相同的。POST则常用于发送一定的内容进行某些修改操作。</p>
</blockquote>
</li>
<li>大小不同<blockquote>
<p>由于不同的浏览器对URL的长度大小有一定的字符限制，因此由于GET方式放在URL的首部中，自然也跟着首先，但是具体的大小要依浏览器而定。POST方式则是把内容放在报文内容中，因此只要报文的内容没有限制，它的大小就没有限制。</p>
</blockquote>
</li>
<li>安全性不同<blockquote>
<p>上面也说了GET是直接添加到URL后面的，直接就可以在URL中看到内容。而POST是放在报文内部的，用户无法直接看到。</p>
</blockquote>
</li>
</ol>
<p>总的来说，GET用于获取某个内容，POST用于提交某种数据请求，从使用场景来看，一般用户注册的内容是私密的，应该使用POST方式来保持私密，而当需要查询某个内容时，需要快速响应，则使用GET。</p>
<h4 id="3-3-status-code状态码"><a href="#3-3-status-code状态码" class="headerlink" title="3.3 status code状态码"></a>3.3 status code状态码</h4><p>状态码通常就是服务器端对客户端说的话，分类如下：</p>
<table>
<thead>
<tr>
<th>状态码</th>
<th>含义</th>
</tr>
</thead>
<tbody>
<tr>
<td>1**</td>
<td>服务器收到请求，需要请求者继续执行操作</td>
</tr>
<tr>
<td>2**</td>
<td>成功，操作被成功接收并处理</td>
</tr>
<tr>
<td>3**</td>
<td>重新定向，需要进一步的操作以完成请求</td>
</tr>
<tr>
<td>4**</td>
<td>客户端错误，请求包含语法错误或无法完成请求</td>
</tr>
<tr>
<td>5**</td>
<td>服务器错误，服务器在处理请求的过程中发生了错误</td>
</tr>
</tbody>
</table>
<p>常见的状态码：</p>
<ul>
<li>200 通常的成功 OK<blockquote>
<p>GET：请求的对应资源会作为响应返回。响应将包含描述或操作的结果。<br>POST：返回处理对应请求的结果。</p>
</blockquote>
</li>
<li>204 成功处理请求，没有返回任何内容 No Content<blockquote>
<p>表示服务器接收到的请求已经处理完毕，但是服务器不需要返回响应。比如，客户端是浏览器的话，那么浏览器显示的页面不会发生更新。</p>
</blockquote>
</li>
<li>206 Partial Content<blockquote>
<p>成功处理了部分GET请求</p>
</blockquote>
</li>
<li>301 Moved Permanently<blockquote>
<p>请求的网页已永久移动到新位置，永久性重定向</p>
</blockquote>
</li>
<li>302 Found<blockquote>
<p>网站临时性重定向，暂时不能访问（备案、被查）</p>
</blockquote>
</li>
<li>303 See Other<blockquote>
<p>该状态码表示由于请求对应的资源存在另一个URI，并指定必须使用GET方法定向获取请求的资源。和302不同的是，302是不会改变上次的请求方法</p>
</blockquote>
</li>
<li>304 Not Modified<blockquote>
<p>访问不了，并返回和上次一样的话,表示资源未被修改过，还是和上次访问时一样。</p>
</blockquote>
</li>
<li>307 Temporary Redirect<blockquote>
<p>临时重定向，和302、303类似，不同的是，不会指定客户端要用什么样的方法请求，</p>
</blockquote>
</li>
<li>400 Bad Request<blockquote>
<p>表示客户端中存在语法错误，导致服务器无法理解该请求。客户端需要修改请求的内容后再次发送请求。</p>
</blockquote>
</li>
<li>401 Unauthorized<blockquote>
<p>即用户没有必要的凭据。该状态码表示当前请求需要用户验证。</p>
</blockquote>
</li>
<li>403 Forbidden<blockquote>
<p>服务器已经理解请求，但是拒绝执行它。</p>
</blockquote>
</li>
<li>404 Not Found<blockquote>
<p>服务器找不到请求的网页。</p>
</blockquote>
</li>
<li>500 Internal Server Error<blockquote>
<p>服务器遇到错误，无法完成请求。</p>
</blockquote>
</li>
<li>503 Service Unavailable<blockquote>
<p>由于临时的服务器维护或者过载，服务器当前无法处理请求。这个状况是暂时的.</p>
</blockquote>
</li>
</ul>
<h4 id="3-4-内容编码-Accept-Encoding"><a href="#3-4-内容编码-Accept-Encoding" class="headerlink" title="3.4 内容编码 Accept Encoding"></a>3.4 内容编码 Accept Encoding</h4><p>由于有些报文的内容会过大，为了减少传输时间，HTTP会采取一些压缩的措施，例如上面的报文信息中，Accept-Encoding 就定义了内容编码的格式gzip。</p>
<p>总的来说内容编码的格式有以下几种：</p>
<ul>
<li>gzip:GNU压缩格式</li>
<li>compress:UNIX系统的标准压缩格式</li>
<li>deflate:是一种同时使用了LZ77和哈夫曼编码的无损失压缩格式</li>
<li>identity:不进行压缩</li>
</ul>
<h4 id="3-5-持久化——connection"><a href="#3-5-持久化——connection" class="headerlink" title="3.5 持久化——connection"></a>3.5 持久化——connection</h4><p>正常发送HTTP时，我们需要建立TCP的连接，然后再发送报文：</p>
<p><img src="https://user-gold-cdn.xitu.io/2018/5/15/16363db63377aff6?w=599&amp;h=259&amp;f=png&amp;s=24567" alt="image"></p>
<p>如果每次都要发送HTTP报文都需要经历上面的过程，这无疑将会耗费很多时间在建立和断开连接的过程中。因此HTTP使用了 connection 属性，用于指定连接的方式。当设置成keep-alive时，就会建立一条持久化的连接。这样就不需要每次都建立连接，再中断连接：</p>
<p><img src="https://user-gold-cdn.xitu.io/2018/5/15/16363db6cfd402bf?w=578&amp;h=243&amp;f=png&amp;s=28374" alt="image"></p>
<p>（HTTP1.1中connection默认开启keep-alive）</p>
<h4 id="3-6-无状态的HTTP——cookie"><a href="#3-6-无状态的HTTP——cookie" class="headerlink" title="3.6 无状态的HTTP——cookie"></a>3.6 无状态的HTTP——cookie</h4><p>由于HTTP是一种无状态的协议，这是由于Web服务器要面对很多浏览器的并发访问，为了提高Web服务器对并发访问的处理能力，在设计HTTP协议时规定，Web服务器发送HTTP应答报文和文档时，不保存发出请求的Web浏览器进程的任何状态信息，从而减轻服务器端的负载，同时无状态也减小了HTTP请求的开销。</p>
<p>但当有些场景需要时刻记住用户的信息时，无状态很明显不能满足需求，因此HTTP提供了cookie来解决这个问题，cookie技术通过在请求和相应报文中写入cookie信息来控制客户端的状态。cookie会根据从服务端发送的相应报文内的一个叫做set-cookie的首部字段信息，通知客户端保存cookie。当下次客户端再往服务器发送请求的时候，客户端会自动在请求头加入cookie值后发送出去。在没有cookie状态下的请求：<br><img src="https://user-gold-cdn.xitu.io/2018/5/15/16363db6d2077346?w=637&amp;h=270&amp;f=png&amp;s=59536" alt="image"></p>
<p>当存有cookie后的请求：</p>
<p><img src="https://user-gold-cdn.xitu.io/2018/5/15/16363db6e9f972fc?w=601&amp;h=243&amp;f=png&amp;s=51496" alt="image"></p>
<p>简单来说Cookie是一种由服务器端确定，并保存在客户端浏览器中的内容。这样每次当我们去添加用户的信息，请求会自动添加cookie中对应的内容。</p>
<p>（关于浏览器端的数据存储感兴趣的可以看下这篇文章：<a href="https://juejin.im/post/5aeaf545518825673b61ddc8" target="_blank" rel="noopener">：聊一聊常见的浏览器端数据存储方案</a>）</p>
<h3 id="3-7-范围请求"><a href="#3-7-范围请求" class="headerlink" title="3.7 范围请求"></a>3.7 范围请求</h3><p>在一些场景下，我们在使用HTTP报文请求一些很大的图片时，加载过程往往会很慢（比如一些摄影网站）。这时候我们就会发现一些图片是一块一块加载的，这是因为设置了HTTP请求的长度，从而分块的加载资源。在请求报文中使用Range属性，在响应报文中使用Content-Type属性都可以进行指定一定自己的HTTP请求。</p>
<h4 id="3-8-报文首部总结"><a href="#3-8-报文首部总结" class="headerlink" title="3.8 报文首部总结"></a>3.8 报文首部总结</h4><p><img src="https://user-gold-cdn.xitu.io/2018/5/15/16363db6e0576c28?w=705&amp;h=1344&amp;f=jpeg&amp;s=151236" alt="image"></p>
<p>（图转自：<a href="http://www.cnblogs.com/xing901022/p/4311987.html）" target="_blank" rel="noopener">http://www.cnblogs.com/xing901022/p/4311987.html）</a></p>
<h3 id="4-HTTP方法"><a href="#4-HTTP方法" class="headerlink" title="4.HTTP方法"></a>4.HTTP方法</h3><p>HTTP 支持几种不同的请求命令，这些命令被称为 HTTP 方法（HTTP method）。每<br>条 HTTP 请求报文都包含一个方法。这个方法会告诉服务器要执行什么动作（获取<br>一个 Web 页面、运行一个网关程序、删除一个文件等）。下表是一些常见的HTTP方法：</p>
<table>
<thead>
<tr>
<th>HTTP方法</th>
<th>描述</th>
</tr>
</thead>
<tbody>
<tr>
<td>GET</td>
<td>从服务器向客户端发送命名资源</td>
</tr>
<tr>
<td>PUT</td>
<td>将来自客户端的数据存储到一个命名的服务器资源中去</td>
</tr>
<tr>
<td>DELETE</td>
<td>从服务器中删除命名资源</td>
</tr>
<tr>
<td>POST</td>
<td>将客户端数据发送到一个服务器网关应用程序</td>
</tr>
<tr>
<td>HEAD</td>
<td>仅发送命名资源响应中的 HTTP 首部</td>
</tr>
</tbody>
</table>
<p>（GET和POST已在上面讨论过了，这里就不在讨论了）</p>
<h4 id="4-1、PUT传输文件"><a href="#4-1、PUT传输文件" class="headerlink" title="4.1、PUT传输文件"></a>4.1、PUT传输文件</h4><p>PUT方法用于传输文件，就像FTP协议的文件上传一样，要求在请求报文的主题中包含文件内容，然后保存到请求URI指定的位置。由于PUT方法不带验证机制，任何人都可以上传文件，所以存在安全性问题，因此一般的web网站不使用该方法。</p>
<h4 id="4-2、DELETE删除文件"><a href="#4-2、DELETE删除文件" class="headerlink" title="4.2、DELETE删除文件"></a>4.2、DELETE删除文件</h4><p>DELETE方法用来删除文件，是与put相反的方法，DELETE方法按照请求url删除指定的资源。其本质和PUT方法一样不带验证机制，所以建议少用DELETE方法。</p>
<h4 id="4-3、HEAD获取报文首部"><a href="#4-3、HEAD获取报文首部" class="headerlink" title="4.3、HEAD获取报文首部"></a>4.3、HEAD获取报文首部</h4><p>HEAD和GET方法一样，只是不返回报文主体部分，通常用于确认url的有效性及资源更新的日期时间等。<br><img src="https://user-gold-cdn.xitu.io/2018/5/15/16363db6f24e7667?w=588&amp;h=91&amp;f=png&amp;s=24582" alt="image"></p>
<h3 id="5-HTTPS"><a href="#5-HTTPS" class="headerlink" title="5.HTTPS"></a>5.HTTPS</h3><h4 id="5-1-什么是HTTPS"><a href="#5-1-什么是HTTPS" class="headerlink" title="5.1 什么是HTTPS"></a>5.1 什么是HTTPS</h4><p>HTTPS（全称：Hyper Text Transfer Protocol over Secure Socket Layer），是以安全为目标的HTTP通道，简单来说就是是HTTP的安全版本，即在HTTP下加入SSL层，HTTPS的安全基石是SSL，因此加密的详细内容就需要SSL。 它现在已经被广泛应用，比如GitHub，支付宝，掘金等。</p>
<h4 id="5-2-为什么需要HTTPS"><a href="#5-2-为什么需要HTTPS" class="headerlink" title="5.2 为什么需要HTTPS"></a>5.2 为什么需要HTTPS</h4><p>这是由于HTTP有这么几个缺点：</p>
<ul>
<li>传输的时候使用明文传输，这显然会可以伪造一些HTTP访问，这显然会造成一些困扰。比如Jmeter就是典型的例子，伪造一大堆的HTTP URL然后压力测试，这也就是DOS攻击的一种。</li>
<li>无法验证报文的完整性，比如一个HTTP的报文已经被不法者截取并且篡改，服务器端也无法验证。<h4 id="5-3-HTTP-与-HTTPS-的区别"><a href="#5-3-HTTP-与-HTTPS-的区别" class="headerlink" title="5.3 HTTP 与 HTTPS 的区别"></a>5.3 HTTP 与 HTTPS 的区别</h4>正是由于以上这些缺点，HTTPS作出了以下一些改变：</li>
<li>HTTP 是明文传输，HTTPS 通过 SSL\TLS 进行了加密</li>
<li>HTTP 的端口号是 80，HTTPS 是 443</li>
<li>HTTPS 需要到 CA 申请证书，一般免费证书很少，需要交费</li>
<li>-HTTPS 的连接很简单，是无状态的；HTTPS 协议是由 SSL+HTTP 协议构建的可进行加密传输、身份认证的网络协议，比 HTTP 协议安全。<h4 id="5-4-HTTPS的缺陷"><a href="#5-4-HTTPS的缺陷" class="headerlink" title="5.4 HTTPS的缺陷"></a>5.4 HTTPS的缺陷</h4>可以说HTTPS相对于HTTP就是套上了黄金甲的圣斗士，变了身的奥特曼，沉睡了的毛利小五郎，不仅仅提升了安全，还提升了逼格。但HTTPS也有一些缺陷：</li>
<li>通信的速度变慢，由于需要加密，一个握手就多了好几个往返</li>
<li>对用户的机器负载的增加。（说出来你们可能不信，我们学校一到晚上，用HTTPS协议的网站基本上都上不了）<br><img src="https://user-gold-cdn.xitu.io/2018/5/15/16363db6fdc9f9e2?w=640&amp;h=485&amp;f=jpeg&amp;s=37246" alt="image"><h3 id="6-HTTP认证"><a href="#6-HTTP认证" class="headerlink" title="6. HTTP认证"></a>6. HTTP认证</h3>有一些网站需要用户的登录从而获取用户的个人信息来进行接下来的操作，因此需要随时知道这些消息，但是肯定不能每次都让用户输入用户密码，这样会让用户感觉很不爽，因此HTTP也自带了认证的功能，认证方式主要如下：</li>
</ul>
<p><img src="https://user-gold-cdn.xitu.io/2018/5/15/16363db708db432c?w=395&amp;h=228&amp;f=jpeg&amp;s=13767" alt="image"></p>
<h4 id="6-1-BASIC认证"><a href="#6-1-BASIC认证" class="headerlink" title="6.1 BASIC认证"></a>6.1 BASIC认证</h4><p>其中BASIC认证是最简单的认证，大致过程如下：</p>
<ol>
<li>客户端访问某URL。</li>
<li>服务器端返回401状态码，提示用户输入用户名密码。</li>
<li>用户输入用户名密码，通过BASE64编码传输。</li>
<li>服务器通过认证，返回状态码200</li>
</ol>
<p>但它有以下缺陷：</p>
<ol>
<li>仅仅通过BASE64编码，其实还是属于明文传输，安全性不高</li>
<li>有的浏览器不支持注销<h4 id="6-2-DIGEST认证"><a href="#6-2-DIGEST认证" class="headerlink" title="6.2 DIGEST认证"></a>6.2 DIGEST认证</h4>正是由于BASIC认证存在弱点，因此从HTTP/1.1起就有了DIGEST认证，DIGEST认证同样使用质询/响应的方式，但不会像BASIC认证那样直接明文发送密码。<br><img src="https://user-gold-cdn.xitu.io/2018/5/15/16363db70a13a202?w=690&amp;h=496&amp;f=jpeg&amp;s=75157" alt="image"><h4 id="6-3-SSL认证（比较常见）"><a href="#6-3-SSL认证（比较常见）" class="headerlink" title="6.3 SSL认证（比较常见）"></a>6.3 SSL认证（比较常见）</h4>SSL客户端认证是借由HTTPS的客户端证书完成认证的方式。凭借客户端证书认证，服务器可确认访问是否来自已登录的客户端。</li>
</ol>
<p>SSL客户端认证的步骤：</p>
<ol>
<li>服务器接收到需要认证资源的请求时，服务器会发送CertificateRequest报文，要求客户端提供客户端证书。</li>
<li>客户端将客户端证书信息以Client Certificate报文方式发送给服务器。</li>
<li>服务器验证客户端证书验证通过后才能领取证书内客户端的公开密钥，然后开始HTTPS加密通信。</li>
</ol>
<p>像支付宝，网银之类对安全要求很高的网站，在登录时，都需要下载一个数字认证，这个数字认证就属于一种SSL客户端的验证。但它的缺点也很明显，需要手动下载，对于现在越来越懒的网民们来讲会感觉很麻烦（包括我）</p>
<h4 id="6-4-表单认证（最常用的）"><a href="#6-4-表单认证（最常用的）" class="headerlink" title="6.4 表单认证（最常用的）"></a>6.4 表单认证（最常用的）</h4><p>最后一种认证方式是最常见的，我们可以通过cookie或session来进行认证。</p>
<h5 id="Session管理和Cookie应用的结合"><a href="#Session管理和Cookie应用的结合" class="headerlink" title="Session管理和Cookie应用的结合"></a>Session管理和Cookie应用的结合</h5><p>我前面提到过，HTTP是无状态协议，无法实现状态管理，因此有了cookie。我们就可以使用Cookie来管理Session（会话），以弥补HTTP协议中不存在的状态管理功能。</p>
<p>认证步骤：</p>
<ol>
<li>客户端把用户的ID和密码等相关信息放入报文的实体部分，然后通常以POST请求的方式发送给服务器。</li>
<li>服务器会发放用以识别用户的Session ID。通过验证从客户端发送过来的登录信息进行身份认证，将用户的认证状态和Session ID绑定后记录在服务器端。</li>
<li>客户端接收到Session ID后，会将其作为Cookie保存在本地。下次向服务器发送请求时，浏览器自动发送Cookie，Session ID会随之发送到服务器。服务端通过验证接收到的Session ID识别用户和其认证状态，然后用户就能执行特定的操作了。</li>
</ol>
<p>参考资料：</p>
<ol>
<li>《图解HTTP》</li>
<li><a href="https://juejin.im/post/59e4c02151882578d02f4aca" target="_blank" rel="noopener">https://juejin.im/post/59e4c02151882578d02f4aca</a></li>
<li><a href="http://www.cnblogs.com/xing901022/p/4309840.html" target="_blank" rel="noopener">http://www.cnblogs.com/xing901022/p/4309840.html</a></li>
</ol>

      
    </div>
    
    
    

    

    

    

    <footer class="post-footer">
      
        <div class="post-tags">
          
            <a href="/blog/tags/HTTP/" rel="tag"># HTTP</a>
          
            <a href="/blog/tags/计算机网络/" rel="tag"># 计算机网络</a>
          
        </div>
      

      
      
      

      
        <div class="post-nav">
          <div class="post-nav-next post-nav-item">
            
              <a href="/blog/2018/05/11/从HTML5 WebSocket到Socket.io/" rel="next" title="从HTML5 WebSocket到Socket.io">
                <i class="fa fa-chevron-left"></i> 从HTML5 WebSocket到Socket.io
              </a>
            
          </div>

          <span class="post-nav-divider"></span>

          <div class="post-nav-prev post-nav-item">
            
              <a href="/blog/2018/05/17/Flex学习笔记/" rel="prev" title="Flex学习笔记">
                Flex学习笔记 <i class="fa fa-chevron-right"></i>
              </a>
            
          </div>
        </div>
      

      
      
    </footer>
  </div>
  
  
  
  </article>



    <div class="post-spread">
      
    </div>
  </div>


          </div>
          


          

  



        </div>
        
          
  
  <div class="sidebar-toggle">
    <div class="sidebar-toggle-line-wrap">
      <span class="sidebar-toggle-line sidebar-toggle-line-first"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-middle"></span>
      <span class="sidebar-toggle-line sidebar-toggle-line-last"></span>
    </div>
  </div>

  <aside id="sidebar" class="sidebar">
    
    <div class="sidebar-inner">

      

      
        <ul class="sidebar-nav motion-element">
          <li class="sidebar-nav-toc sidebar-nav-active" data-target="post-toc-wrap">
            文章目录
          </li>
          <li class="sidebar-nav-overview" data-target="site-overview-wrap">
            站点概览
          </li>
        </ul>
      

      <section class="site-overview-wrap sidebar-panel">
        <div class="site-overview">
          <div class="site-author motion-element" itemprop="author" itemscope itemtype="http://schema.org/Person">
            
              <img class="site-author-image" itemprop="image"
                src="/blog/images/avatar.jpg"
                alt="Srtian" />
            
              <p class="site-author-name" itemprop="name">Srtian</p>
              <p class="site-description motion-element" itemprop="description">JUST DO IT.</p>
          </div>

          <nav class="site-state motion-element">

            
              <div class="site-state-item site-state-posts">
              
                <a href="/blog/archives/">
              
                  <span class="site-state-item-count">59</span>
                  <span class="site-state-item-name">日志</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-categories">
                <a href="/blog/categories/index.html">
                  <span class="site-state-item-count">15</span>
                  <span class="site-state-item-name">分类</span>
                </a>
              </div>
            

            
              
              
              <div class="site-state-item site-state-tags">
                <a href="/blog/tags/index.html">
                  <span class="site-state-item-count">37</span>
                  <span class="site-state-item-name">标签</span>
                </a>
              </div>
            

          </nav>

          

          
            <div class="links-of-author motion-element">
                
                  <span class="links-of-author-item">
                    <a href="https://gitee.com/srtian96" target="_blank" title="GitHub">
                      
                        <i class="fa fa-fw fa-github"></i>GitHub</a>
                  </span>
                
                  <span class="links-of-author-item">
                    <a href="shenruotian@gmail.com" target="_blank" title="E-Mail">
                      
                        <i class="fa fa-fw fa-envelope"></i>E-Mail</a>
                  </span>
                
            </div>
          

          
          

          
          

          

        </div>
      </section>

      
      <!--noindex-->
        <section class="post-toc-wrap motion-element sidebar-panel sidebar-panel-active">
          <div class="post-toc">

            
              
            

            
              <div class="post-toc-content"><ol class="nav"><li class="nav-item nav-level-3"><a class="nav-link" href="#1-HTTP简述（出自MDN）"><span class="nav-number">1.</span> <span class="nav-text">1.HTTP简述（出自MDN）</span></a></li><li class="nav-item nav-level-3"><a class="nav-link" href="#2-URL和URI"><span class="nav-number">2.</span> <span class="nav-text">2.URL和URI</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#2-1-URL"><span class="nav-number">2.1.</span> <span class="nav-text">2.1 URL</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-HTTP报文"><span class="nav-number">3.</span> <span class="nav-text">3.HTTP报文</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#3-1-HTTP报文格式"><span class="nav-number">3.1.</span> <span class="nav-text">3.1 HTTP报文格式</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-2-HTTP请求方式（request-method）——GET-and-POST"><span class="nav-number">3.2.</span> <span class="nav-text">3.2 HTTP请求方式（request method）——GET and POST</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-3-status-code状态码"><span class="nav-number">3.3.</span> <span class="nav-text">3.3 status code状态码</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-4-内容编码-Accept-Encoding"><span class="nav-number">3.4.</span> <span class="nav-text">3.4 内容编码 Accept Encoding</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-5-持久化——connection"><span class="nav-number">3.5.</span> <span class="nav-text">3.5 持久化——connection</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#3-6-无状态的HTTP——cookie"><span class="nav-number">3.6.</span> <span class="nav-text">3.6 无状态的HTTP——cookie</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#3-7-范围请求"><span class="nav-number">4.</span> <span class="nav-text">3.7 范围请求</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#3-8-报文首部总结"><span class="nav-number">4.1.</span> <span class="nav-text">3.8 报文首部总结</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#4-HTTP方法"><span class="nav-number">5.</span> <span class="nav-text">4.HTTP方法</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#4-1、PUT传输文件"><span class="nav-number">5.1.</span> <span class="nav-text">4.1、PUT传输文件</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-2、DELETE删除文件"><span class="nav-number">5.2.</span> <span class="nav-text">4.2、DELETE删除文件</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#4-3、HEAD获取报文首部"><span class="nav-number">5.3.</span> <span class="nav-text">4.3、HEAD获取报文首部</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#5-HTTPS"><span class="nav-number">6.</span> <span class="nav-text">5.HTTPS</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#5-1-什么是HTTPS"><span class="nav-number">6.1.</span> <span class="nav-text">5.1 什么是HTTPS</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#5-2-为什么需要HTTPS"><span class="nav-number">6.2.</span> <span class="nav-text">5.2 为什么需要HTTPS</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#5-3-HTTP-与-HTTPS-的区别"><span class="nav-number">6.3.</span> <span class="nav-text">5.3 HTTP 与 HTTPS 的区别</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#5-4-HTTPS的缺陷"><span class="nav-number">6.4.</span> <span class="nav-text">5.4 HTTPS的缺陷</span></a></li></ol></li><li class="nav-item nav-level-3"><a class="nav-link" href="#6-HTTP认证"><span class="nav-number">7.</span> <span class="nav-text">6. HTTP认证</span></a><ol class="nav-child"><li class="nav-item nav-level-4"><a class="nav-link" href="#6-1-BASIC认证"><span class="nav-number">7.1.</span> <span class="nav-text">6.1 BASIC认证</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#6-2-DIGEST认证"><span class="nav-number">7.2.</span> <span class="nav-text">6.2 DIGEST认证</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#6-3-SSL认证（比较常见）"><span class="nav-number">7.3.</span> <span class="nav-text">6.3 SSL认证（比较常见）</span></a></li><li class="nav-item nav-level-4"><a class="nav-link" href="#6-4-表单认证（最常用的）"><span class="nav-number">7.4.</span> <span class="nav-text">6.4 表单认证（最常用的）</span></a><ol class="nav-child"><li class="nav-item nav-level-5"><a class="nav-link" href="#Session管理和Cookie应用的结合"><span class="nav-number">7.4.1.</span> <span class="nav-text">Session管理和Cookie应用的结合</span></a></li></ol></li></ol></li></ol></div>
            

          </div>
        </section>
      <!--/noindex-->
      

      

    </div>
  </aside>


        
      </div>
    </main>

    <footer id="footer" class="footer">
      <div class="footer-inner">
        <div class="copyright">&copy; <span itemprop="copyrightYear">2019</span>
  <span class="with-love">
    <i class="fa fa-user"></i>
  </span>
  <span class="author" itemprop="copyrightHolder">Srtian</span>
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js">
</script>
  
    <span class="post-meta-divider">|</span>
    <span class="post-meta-item-icon">
      <i class="fa fa-area-chart"></i>
    </span>
    
      <span class="post-meta-item-text">Site words total count&#58;</span>
    
    <span title="Site words total count">102.8k</span>
  
</div>





        
<div class="busuanzi-count">
  <script async src="https://dn-lbstatics.qbox.me/busuanzi/2.3/busuanzi.pure.mini.js"></script>

  
    <span class="site-uv">
      本站访客数
      <span class="busuanzi-value" id="busuanzi_value_site_uv"></span>
      人次
    </span>
  

  
    <span class="site-pv">
      本站总访问量
      <span class="busuanzi-value" id="busuanzi_value_site_pv"></span>
      次
    </span>
  
</div>








        
      </div>
    </footer>

    
      <div class="back-to-top">
        <i class="fa fa-arrow-up"></i>
        
      </div>
    

    

  </div>

  

<script type="text/javascript">
  if (Object.prototype.toString.call(window.Promise) !== '[object Function]') {
    window.Promise = null;
  }
</script>









  












  
  
    <script type="text/javascript" src="/blog/lib/jquery/index.js?v=2.1.3"></script>
  

  
  
    <script type="text/javascript" src="/blog/lib/fastclick/lib/fastclick.min.js?v=1.0.6"></script>
  

  
  
    <script type="text/javascript" src="/blog/lib/jquery_lazyload/jquery.lazyload.js?v=1.9.7"></script>
  

  
  
    <script type="text/javascript" src="/blog/lib/velocity/velocity.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/blog/lib/velocity/velocity.ui.min.js?v=1.2.1"></script>
  

  
  
    <script type="text/javascript" src="/blog/lib/fancybox/source/jquery.fancybox.pack.js?v=2.1.5"></script>
  


  


  <script type="text/javascript" src="/blog/js/src/utils.js?v=5.1.4"></script>

  <script type="text/javascript" src="/blog/js/src/motion.js?v=5.1.4"></script>



  
  


  <script type="text/javascript" src="/blog/js/src/affix.js?v=5.1.4"></script>

  <script type="text/javascript" src="/blog/js/src/schemes/pisces.js?v=5.1.4"></script>



  
  <script type="text/javascript" src="/blog/js/src/scrollspy.js?v=5.1.4"></script>
<script type="text/javascript" src="/blog/js/src/post-details.js?v=5.1.4"></script>



  


  <script type="text/javascript" src="/blog/js/src/bootstrap.js?v=5.1.4"></script>



  


  




	





  





  












  

  <script type="text/javascript">
    // Popup Window;
    var isfetched = false;
    var isXml = true;
    // Search DB path;
    var search_path = "search.xml";
    if (search_path.length === 0) {
      search_path = "search.xml";
    } else if (/json$/i.test(search_path)) {
      isXml = false;
    }
    var path = "/blog/" + search_path;
    // monitor main search box;

    var onPopupClose = function (e) {
      $('.popup').hide();
      $('#local-search-input').val('');
      $('.search-result-list').remove();
      $('#no-result').remove();
      $(".local-search-pop-overlay").remove();
      $('body').css('overflow', '');
    }

    function proceedsearch() {
      $("body")
        .append('<div class="search-popup-overlay local-search-pop-overlay"></div>')
        .css('overflow', 'hidden');
      $('.search-popup-overlay').click(onPopupClose);
      $('.popup').toggle();
      var $localSearchInput = $('#local-search-input');
      $localSearchInput.attr("autocapitalize", "none");
      $localSearchInput.attr("autocorrect", "off");
      $localSearchInput.focus();
    }

    // search function;
    var searchFunc = function(path, search_id, content_id) {
      'use strict';

      // start loading animation
      $("body")
        .append('<div class="search-popup-overlay local-search-pop-overlay">' +
          '<div id="search-loading-icon">' +
          '<i class="fa fa-spinner fa-pulse fa-5x fa-fw"></i>' +
          '</div>' +
          '</div>')
        .css('overflow', 'hidden');
      $("#search-loading-icon").css('margin', '20% auto 0 auto').css('text-align', 'center');

      $.ajax({
        url: path,
        dataType: isXml ? "xml" : "json",
        async: true,
        success: function(res) {
          // get the contents from search data
          isfetched = true;
          $('.popup').detach().appendTo('.header-inner');
          var datas = isXml ? $("entry", res).map(function() {
            return {
              title: $("title", this).text(),
              content: $("content",this).text(),
              url: $("url" , this).text()
            };
          }).get() : res;
          var input = document.getElementById(search_id);
          var resultContent = document.getElementById(content_id);
          var inputEventFunction = function() {
            var searchText = input.value.trim().toLowerCase();
            var keywords = searchText.split(/[\s\-]+/);
            if (keywords.length > 1) {
              keywords.push(searchText);
            }
            var resultItems = [];
            if (searchText.length > 0) {
              // perform local searching
              datas.forEach(function(data) {
                var isMatch = false;
                var hitCount = 0;
                var searchTextCount = 0;
                var title = data.title.trim();
                var titleInLowerCase = title.toLowerCase();
                var content = data.content.trim().replace(/<[^>]+>/g,"");
                var contentInLowerCase = content.toLowerCase();
                var articleUrl = decodeURIComponent(data.url);
                var indexOfTitle = [];
                var indexOfContent = [];
                // only match articles with not empty titles
                if(title != '') {
                  keywords.forEach(function(keyword) {
                    function getIndexByWord(word, text, caseSensitive) {
                      var wordLen = word.length;
                      if (wordLen === 0) {
                        return [];
                      }
                      var startPosition = 0, position = [], index = [];
                      if (!caseSensitive) {
                        text = text.toLowerCase();
                        word = word.toLowerCase();
                      }
                      while ((position = text.indexOf(word, startPosition)) > -1) {
                        index.push({position: position, word: word});
                        startPosition = position + wordLen;
                      }
                      return index;
                    }

                    indexOfTitle = indexOfTitle.concat(getIndexByWord(keyword, titleInLowerCase, false));
                    indexOfContent = indexOfContent.concat(getIndexByWord(keyword, contentInLowerCase, false));
                  });
                  if (indexOfTitle.length > 0 || indexOfContent.length > 0) {
                    isMatch = true;
                    hitCount = indexOfTitle.length + indexOfContent.length;
                  }
                }

                // show search results

                if (isMatch) {
                  // sort index by position of keyword

                  [indexOfTitle, indexOfContent].forEach(function (index) {
                    index.sort(function (itemLeft, itemRight) {
                      if (itemRight.position !== itemLeft.position) {
                        return itemRight.position - itemLeft.position;
                      } else {
                        return itemLeft.word.length - itemRight.word.length;
                      }
                    });
                  });

                  // merge hits into slices

                  function mergeIntoSlice(text, start, end, index) {
                    var item = index[index.length - 1];
                    var position = item.position;
                    var word = item.word;
                    var hits = [];
                    var searchTextCountInSlice = 0;
                    while (position + word.length <= end && index.length != 0) {
                      if (word === searchText) {
                        searchTextCountInSlice++;
                      }
                      hits.push({position: position, length: word.length});
                      var wordEnd = position + word.length;

                      // move to next position of hit

                      index.pop();
                      while (index.length != 0) {
                        item = index[index.length - 1];
                        position = item.position;
                        word = item.word;
                        if (wordEnd > position) {
                          index.pop();
                        } else {
                          break;
                        }
                      }
                    }
                    searchTextCount += searchTextCountInSlice;
                    return {
                      hits: hits,
                      start: start,
                      end: end,
                      searchTextCount: searchTextCountInSlice
                    };
                  }

                  var slicesOfTitle = [];
                  if (indexOfTitle.length != 0) {
                    slicesOfTitle.push(mergeIntoSlice(title, 0, title.length, indexOfTitle));
                  }

                  var slicesOfContent = [];
                  while (indexOfContent.length != 0) {
                    var item = indexOfContent[indexOfContent.length - 1];
                    var position = item.position;
                    var word = item.word;
                    // cut out 100 characters
                    var start = position - 20;
                    var end = position + 80;
                    if(start < 0){
                      start = 0;
                    }
                    if (end < position + word.length) {
                      end = position + word.length;
                    }
                    if(end > content.length){
                      end = content.length;
                    }
                    slicesOfContent.push(mergeIntoSlice(content, start, end, indexOfContent));
                  }

                  // sort slices in content by search text's count and hits' count

                  slicesOfContent.sort(function (sliceLeft, sliceRight) {
                    if (sliceLeft.searchTextCount !== sliceRight.searchTextCount) {
                      return sliceRight.searchTextCount - sliceLeft.searchTextCount;
                    } else if (sliceLeft.hits.length !== sliceRight.hits.length) {
                      return sliceRight.hits.length - sliceLeft.hits.length;
                    } else {
                      return sliceLeft.start - sliceRight.start;
                    }
                  });

                  // select top N slices in content

                  var upperBound = parseInt('1');
                  if (upperBound >= 0) {
                    slicesOfContent = slicesOfContent.slice(0, upperBound);
                  }

                  // highlight title and content

                  function highlightKeyword(text, slice) {
                    var result = '';
                    var prevEnd = slice.start;
                    slice.hits.forEach(function (hit) {
                      result += text.substring(prevEnd, hit.position);
                      var end = hit.position + hit.length;
                      result += '<b class="search-keyword">' + text.substring(hit.position, end) + '</b>';
                      prevEnd = end;
                    });
                    result += text.substring(prevEnd, slice.end);
                    return result;
                  }

                  var resultItem = '';

                  if (slicesOfTitle.length != 0) {
                    resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + highlightKeyword(title, slicesOfTitle[0]) + "</a>";
                  } else {
                    resultItem += "<li><a href='" + articleUrl + "' class='search-result-title'>" + title + "</a>";
                  }

                  slicesOfContent.forEach(function (slice) {
                    resultItem += "<a href='" + articleUrl + "'>" +
                      "<p class=\"search-result\">" + highlightKeyword(content, slice) +
                      "...</p>" + "</a>";
                  });

                  resultItem += "</li>";
                  resultItems.push({
                    item: resultItem,
                    searchTextCount: searchTextCount,
                    hitCount: hitCount,
                    id: resultItems.length
                  });
                }
              })
            };
            if (keywords.length === 1 && keywords[0] === "") {
              resultContent.innerHTML = '<div id="no-result"><i class="fa fa-search fa-5x" /></div>'
            } else if (resultItems.length === 0) {
              resultContent.innerHTML = '<div id="no-result"><i class="fa fa-frown-o fa-5x" /></div>'
            } else {
              resultItems.sort(function (resultLeft, resultRight) {
                if (resultLeft.searchTextCount !== resultRight.searchTextCount) {
                  return resultRight.searchTextCount - resultLeft.searchTextCount;
                } else if (resultLeft.hitCount !== resultRight.hitCount) {
                  return resultRight.hitCount - resultLeft.hitCount;
                } else {
                  return resultRight.id - resultLeft.id;
                }
              });
              var searchResultList = '<ul class=\"search-result-list\">';
              resultItems.forEach(function (result) {
                searchResultList += result.item;
              })
              searchResultList += "</ul>";
              resultContent.innerHTML = searchResultList;
            }
          }

          if ('auto' === 'auto') {
            input.addEventListener('input', inputEventFunction);
          } else {
            $('.search-icon').click(inputEventFunction);
            input.addEventListener('keypress', function (event) {
              if (event.keyCode === 13) {
                inputEventFunction();
              }
            });
          }

          // remove loading animation
          $(".local-search-pop-overlay").remove();
          $('body').css('overflow', '');

          proceedsearch();
        }
      });
    }

    // handle and trigger popup window;
    $('.popup-trigger').click(function(e) {
      e.stopPropagation();
      if (isfetched === false) {
        searchFunc(path, 'local-search-input', 'local-search-result');
      } else {
        proceedsearch();
      };
    });

    $('.popup-btn-close').click(onPopupClose);
    $('.popup').click(function(e){
      e.stopPropagation();
    });
    $(document).on('keyup', function (event) {
      var shouldDismissSearchPopup = event.which === 27 &&
        $('.search-popup').is(':visible');
      if (shouldDismissSearchPopup) {
        onPopupClose();
      }
    });
  </script>





  

  

  

  
  

  

  

  

</body>
</html>
